<?php
/*
 * License:
 * =============================================================================
 * Copyright 2007  PANEL Martin
 * email : xxorax@gmail.com
 * website : http://www.xorax.info
 * 
 * This work is licensed under a Creative Commons Attribution-Share Alike 3.0
 * License (http://creativecommons.org/licenses/by-sa/3.0/).
*/

if(!class_exists('readthis')){
class readthis {
  var $posts_audio; // link = post_name associed, id = ID of post associed, sound = url of mp3 on readspeaker
  var $err;
  var $url_fopen;
  var $fields;
  var $opt;
  
  /****** REGISTERING METHODS ******/
  function menu (){
    return array('Add a speaker for your post', 'ReadThis');
  }
  
  function head(){
    ?><script type="text/javascript">var posts_audio = [];</script><?php
  }
  
  function title(){
    ?>ReadThis <a href="<?php echo get_bloginfo('siteurl').'/'.PLUGINDIR.'/readthis/tuto.php'; ?>" target="_blank">? HELP ?</a><?php
  }
  /****** END OF REGISTERING METHODS ******/
  
  function readthis () {
    global $plugin_page;
    //error_reporting(E_ALL);
    
    $this->posts_audio = false;
    
    $this->options = array(
      'admin' => get_option('readthis_opt_admin'),
      'default' => get_option('readthis_opt')
    );
    if(!$this->options['admin']){
      $this->options['admin'] = array(
        'pass2get' => substr(md5(rand()+time()),-15),
        'posts2get' => array(),
        'url' => ''
      );
      add_option("readthis_opt_admin",$this->options['admin'],'','no');
    }
    
    @ini_set('max_execution_time', 10000);
    
    $fields_setup = array('set_url', 'pass2get');
    $fields_usual = array('repport','template_method','template_select');
    //$fields = array_merge($fields, array('path', 'method2get','set_getposts'));
    if(!$this->option('url')){
      $fields = array_merge($fields_setup,$fields_usual);
    } else {
      $fields = array_merge($fields_usual, $fields_setup);
    }

    //$this->xorax_wp_ajax($field);
    $this->fields = $fields;
  }
  
  function option($opt, $value = null, $cache = true){
    if(isset($this->options['admin'][$opt])){
      $is_admin = true;
    } elseif (isset($this->options['default'][$opt])){
      $is_admin = false;
    } else return false;
    
    if($is_admin){
      $opttag = 'admin';
      $dbtag = 'readthis_opt_admin';
    } else {
      $opttag = 'default';
      $dbtag = 'readthis_opt';
    }
    
    if($cache) $GLOBALS['wp_object_cache']->cache_enabled = false;
    
    if(isset($value)){
      $this->options[$opttag][$opt] = $value;
      return update_option($dbtag,$this->options[$opttag]);
      /*if($is_admin){
        $this->options['admin'][$opt] = $value;
        return update_option('readthis_opt_admin',$this->options['admin']);
      } else {
        $this->options['default'][$opt] = $value;
        return update_option('readthis_opt',$this->options['default']);
      }*/
    } else {
      if(!$cache){
        wp_cache_delete($dbtag,'options');
        /* for backward compatibility
        // wordpress don't delete cache when an option is set with autoload
        // param as 'on' (since wp 2.2.1)
        // I open ticket : http://trac.wordpress.org/ticket/4540
        // But wp developer say it's "normal" and I could used an other
        // method... :@ www.dotclear.net
        $alloptions = wp_load_alloptions();
        if ( isset($alloptions['readthis_posts2get']) ) {
          unset($alloptions['readthis_posts2get']);
          wp_cache_set('alloptions', $alloptions, 'options');
        }
        $this->options[$opttag] = get_option($dbtag);
        /**/
      }
        
      return $this->options[$opttag][$opt];
    }
  }
  /*
  function download($id, $override = true){
    if(!$this->get_posts_audio($id)) return false;
    $pa = &$this->posts_audio;
    for($i=0, $n = count($pa); $i < $n; $i++){
      $this->save($pa[$i]['sound'], $pa[$i]['name'], $override);
    }
    return true;
  }*/
  
  function download($url, $file = false){
    if (ini_get('allow_url_fopen')){
      return ($file)? copy($url, $file) : file_get_contents($url);
    } elseif (function_exists('curl_init')){
      $ch = curl_init($url);
      //curl_setopt($ch, CURLOPT_URL, );
      curl_setopt($ch, CURLOPT_HEADER, 1);
      curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
      curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
      curl_setopt($ch, CURLOPT_TIMEOUT, 40);
      curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
      if($file){
        if(false === $fh = @fopen($file,'wb')) return false;
        curl_setopt($ch,CURLOPT_FILE,$fh);
      } else {
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
      }
      return curl_exec($ch);
    }else{
      return false; // TODO
    }
  }
  
  function save($url, $name, $override = true){
    $file = file_post2audio($name);
    $fe = file_exists($file); 
    if( $fe ){
      if(!$override) return true; //exit if do not replace the existing file
      $time = time();
      @rename($file, $file.$time);
    }

    if($this->download($url, $file)){
      if($fe) @unlink($file.$time);
      return true;
    }
    @unlink($file);
    $this->error(__("can't download $url !",'readthis'));
    @rename($file.$time, $file);
    return false;
  }
  
  function error ($s){
    if(!is_array($this->err)) $this->err = array();
    $this->err[] = $s;
  }
  
  function get_posts_audio($ids){
    global $wpdb;
    if(!is_array($ids)) return false;
    if(!empty($this->posts_audio)){
      return true;
    }
    $src = $this->option('url');
    
    $error = false;
    if(empty($src)) {
      $this->error(__("You must set your ReadSpeaker XML URL",'readthis'));
      return false;
    }
    //$GLOBALS['wp_object_cache']->cache_enabled = false;
    //update_option('readthis_posts2get',$ids);
    $this->option('posts2get', $ids, false);
    $cdel = wp_cache_delete('readthis_posts2get','options');
    $xml = $this->download($src);
    if (empty($xml)) {
      $this->error(__("ReadSpeaker URL can't be loaded",'readthis'));
      return false;
    }
    /* for backward compatibility
    if(get_option('readthis_posts2get') != 'ok' ){
      // wordpress don't delete cache when an option is set with autoload
      // param as 'on'.
      // I open ticket : http://trac.wordpress.org/ticket/4540
      // But wp developer say it's "normal" and I could used an other
      // method... :@ www.dotclear.net
      $alloptions = wp_load_alloptions();
      if ( isset($alloptions['readthis_posts2get']) ) {
        unset($alloptions['readthis_posts2get']);
        wp_cache_set('alloptions', $alloptions, 'options');
      }
    }*/
    
    //elseif(get_option('readthis_posts2get') != 'ok' ){
    elseif($this->option('posts2get', null, false) != 'ok' ){
      $this->error(htmlentities(__("Returned status code is not correct",'readthis')));
      return false;
    } elseif(!$this->parse_xml($xml)){
      $this->error(__('ReadSpeaker XML is not valid','readthis'));
      return false;
    } else return true;
    //update_option("readthis_posts2get",$this->posts2get);
  }
  
  //TODO
  function download_audio($_post = null){
    global $post;
    if(empty($_post)) $_post = &$post;
    if(is_numeric($_post)){
      $id = $_post;
      $_post =& get_post($id);
    }
  }

  function parse_xml (&$data){
    global $readthis_var;
    $readthis_var['link_ok'] = false;
    $readthis_var['in_link'] = false;
    $readthis_var['in_item'] = false;
    $readthis_var['temp_name'] = '';
    $this->posts_audio = array();
    $readthis_var['posts_audio'] = & $this->posts_audio;
    
    $parser = xml_parser_create();
    xml_set_element_handler($parser,array(&$this,'xb'),array(&$this,'xe'));
    xml_set_character_data_handler($parser, array(&$this,'xd'));
    
    $func = create_function('$o',
        'global $readthis_var; $p = $o;' .
        'if(count($p)>0) $p = $p[0];' .
        '$readthis_var["temp_name"] = $p->post_name;' .
        'return $o;'
        );
    add_filter('the_posts',$func); // filter called when url_to_postid()
    $x = xml_parse($parser, $data, true);
    remove_filter('the_posts',$func);
    if(!$x){
      $this->posts_audio = false;
      $this->error(sprintf('XML error: %s at line %d',
                    xml_error_string(xml_get_error_code($parser)),
                    xml_get_current_line_number($parser)));
      return false;
    } else {
      if(!$this->posts_audio){
        if($readthis_var['posts_audio']){
          $this->posts_audio = $readthis_var['posts_audio'];
        }
      }
      unset($readthis_var);
      return true;
    }
  }
  
  function xb($parser, $name, $attr){
    global $readthis_var, $wpdb;
    $name = strtolower($name);
    if($readthis_var['in_item']){
      if($name == 'link'){
        $readthis_var['in_link'] = true;
      }elseif($name == 'enclosure'){
        $id = url_to_postid($readthis_var['link_ok']); // and $readthis_var['temp_name'] is set with the temporary added filter 'the_post'
        //* backward compatibility ??
        // since too long time, the next is added to fill the bug of the
        // url_to_postid function which don't find static page (post_type = page)...
        // http://trac.wordpress.org/ticket/4103
        if(!$id){
          $pages =  'pagename='.preg_replace('#^.+/([^/]+)/?$#','$1',$readthis_var['link_ok']);
          $query = new WP_Query($pages);
          if($query->is_page){
            $id = $query->post->ID;
            $readthis_var['temp_name'] = $query->post->post_name;
          }
        }
        /**/
        if(empty($readthis_var['temp_name'])) $readthis_var['temp_name'] = 'unknown_post';
        
        $readthis_var['posts_audio'][] = array(
          'link' => $readthis_var['link_ok'],
          'id' => $id,
          'sound' => $attr['URL'],
          'name' => $readthis_var['temp_name'] //basename($readthis_var['link_ok'])
        );
        $readthis_var['temp_name'] = $id = '';
      }
    } elseif($name=='item'){
      $readthis_var['in_item'] = true;
    }
  }
  
  function xe ($parser, $name){
    global $readthis_var;
    $name = strtolower($name);
    if($name == 'item'){
      $readthis_var['in_item'] = $readthis_var['link_ok'] = false;
    } elseif ($name == 'link'){
      $readthis_var['in_link'] = false;
    }
  }
  
  function xd ($parser, $data){
    global $readthis_var;
    if($readthis_var['in_item'] && $readthis_var['in_link']){
      $readthis_var['link_ok'] = $data;
    }
  }
  
  function get_template_data($file){
    $data = file_get_contents($file);
    $params = array('ReadThis Template Name','ReadThis Template URI','Description','Version','Author','Author URI');
    $matchs = array();
    foreach($params as $param){
      preg_match('#'.$param.'\s*:(.*)$#mi',$data,$m);
      $matchs[$param] = trim($m[1]);
    }
    $matchs['Description'] = wptexturize($matchs['Description']);
    return $matchs;
  }
  
  function get_template($name, $info = true){
    $file = trailingslashit(READTHIS_TPL_DIR).$name.'/'.$name.'.php';
    $template = false;
    if(is_file($file)) {
      $template =  array(
        'name' => $name,
        'file' => $file
      );
      if($info) $template['info'] = $this->get_template_data($file);
    }
    return $template;
  }
  
  function list_template(){
    $templates = array();
    $template_dir = trailingslashit(READTHIS_TPL_DIR);

    if (($dh = @opendir(untrailingslashit($template_dir))) !== false ) {
      while (($name = readdir($dh)) !== false) {
        if($name != '..' && $name != '.' 
          //&& is_dir($template_dir.$name) //optionnal
          && $template = $this->get_template($name)
          ){
          $templates[] = $template;
        }
      }
      closedir($dh);
    }
    return $templates;
  }
  
  function list_audio_files(){
    $audio_files = array();
    $noscan = array('.','..','.htaccess'); 
    if (false !== $dh = @opendir(ABSPATH.untrailingslashit($this->option('audiopath'))) ) {
         while (($file = readdir($dh)) !== false) {
             if(!in_array($file,$noscan)) $audio_files[] =  $file;
         }
         closedir($dh);
    }
    return $audio_files;
  }
  
  function save_callback($url, $name, $post_url){
    $saved = $this->save($url,$name, true);
    $ln = "\n";
    /*$js = 'var d = Builder.node("div", {style:"float:left; border: 1px solid #000099; padding: 3px; margin: 5px;"});'.$ln;
    $js .= 'var br = Builder.node("br");'.$ln;
    $js .= 'var p = Builder.node("a",{href:"'.$post_url.'"},"'.basename($post_url).'");'.$ln;
    if($saved){
      $js .= 'var f = Builder.node("a",{href:"'.file_post2audio($name, true).'"},"'.basename($saved).'");'.$ln;
    } else {
      $js .= 'var f = Builder.node("b","error");'.$ln;
    }
    $js .= 'd.appendChild(p); d.appendChild(br); d.appendChild(f);'.$ln;
    $js .= '$("repport--foot").appendChild(d);'.$ln;
    $js .= 'new Effect.Highlight(d,{duration: 2});'.$ln;*/
    $js = 'repport_status.display({' .
        'post_url:"'.$post_url.'",' .
        'post_url_basename:"'.basename($post_url).'",' .
        'saved_url:"'.file_post2audio($name, true).'",' .
        'saved_name:"'.basename($saved).'"' .
        '});'.$ln;
    $js .= 'repport_status.count++;'.$ln;
    $js .= 'repport_status.onComplete();'.$ln;
    if($this->option('method2get') == 'ajax1by1'){
      $js .= 'if(posts_audio.length) xorax_wp_ajax_callback("save_callback",posts_audio.shift() );';
    } else {
      //$js .= 'if(Ajax.activeRequestCount == 0) xorax_wp_ajax_reload_field("repport");';
    }
    return $js;
  }
  
  function edit_box(){
    $a = get_the_audio_url(true);
    ?><fieldset id="readthisdiv" class="dbx-box">
    <h3 class="dbx-handle">ReadThis <?php _e('Post Author'); ?></h3>
    <div class="dbx-content"><?php
    if($a) _e('a file audio is present for this post.');
    else _e('this post has no audio file.');
    ?></div></fieldset><?php
  }
  
  function field_repport_action(){
    global $wpdb;
    $method2get = $this->option('method2get');
    if(!$this->option('url')) {
      return _e('the URL of the ReadSpeaker\'s XML is empty. You <b>MUST</b> set it to perform this action. check also the method of downloading.');
    } 
    $repport = unserialize(base64_decode($_POST['readthis_file_repport_array']));
    
    switch($_POST['readthis_dl_mode']){
    case 'obsolete_missed':
      $repport = array_merge($repport['obsolete_id'], $repport['missed_id']);
      break;
    case 'obsolete':
      $repport = $repport['obsolete_id'];
      break;
    case 'missed':
      $repport = $repport['missed_id'];
      break;
    case 'all':
      $repport = array_merge($repport['obsolete_id'], $repport['missed_id'], $repport['ok_id']);
      break;
    case 'delete':
      if($method2get == 'url') {
        foreach(array_keys($repport['files']) as $k){
          readthis_meta($k, false);
        }
      } else {
        foreach($repport['files'] as $f){
          @unlink(ABSPATH.$this->option('audiopath').$f);
        }
      }
      echo 'all files removed';
      return array('reload' => true);
    }
    if(empty($repport)){
      _e('none audio files to download','readthis');
    } elseif($this->get_posts_audio($repport)){
      if($method2get == 'server'){
        for($i=0, $n = count($this->posts_audio); $i < $n; $i++){
          $this->save($this->posts_audio[$i]['sound'], $this->posts_audio[$i]['name'], true);
        }
        echo $n.' '.__('audio files saved','readthis');
      } elseif($method2get == 'url'){ //file is url
        $arr = array('upd'=>time());
        $ret = '';
        for($i=0, $n = count($this->posts_audio); $i < $n; $i++){
          $arr['url'] = $this->posts_audio[$i]['sound'];
          readthis_meta($this->posts_audio[$i]['id'], $arr);
          //echo $this->posts_audio[$i]['id'].' : '.$arr['url'];
          $ret .= '<div style="float:left; border: 1px solid #000099; padding: 3px; margin: 5px;">';
          $ret .= '<a href="'.$this->posts_audio[$i]['link'].'">'.basename($this->posts_audio[$i]['link']).'</a><br />';
          $ret .= '<a href="'.$this->posts_audio[$i]['sound'].'">'.basename($this->posts_audio[$i]['sound']).'</a></div>';
          //$this->posts_audio[$i]['id']
        }
        echo $ret;
        return array('reload' => true);
      } else { // method2get = ajaxallin1 or ajax1by1
        $eval = "posts_audio = [";
        for($i=0,$n = count($this->posts_audio); $i < $n; $i++){
          $pa = &$this->posts_audio[$i];
          $eval .= "'".base64_encode(serialize(array($pa['sound'],$pa['name'],$pa['link'])))."',";
        }
        $eval = substr($eval,0,-1)."];\n";
        $eval .= <<<JSEVAL
var repport_status = {
  total: 0,
  count: 0,
  onComplete: function(){
    var p = Math.round(100*this.count/this.total);
    $("repport---percent").innerHTML = p + " %";
    if(p == 100){
      $("repport---status").innerHTML = "Download complete"; 
      new Effect.Highlight("repport---status",{duration: 8, startcolor:"#FFFFAA", endcolor:"#2685AF", restorecolor:"#2685AF"});
      repport_status = null;
      xorax_wp_ajax_reload_field("repport");
    } else new Effect.Highlight("repport---status",{duration: 1, startcolor:"#0000AA"});
  },
  display: function(obj){
    var d = Builder.node("div", {style:"float:left; border: 1px solid #000099; padding: 3px; margin: 5px;"});
    var br = Builder.node("br");
    if(obj.post_url && obj.post_url_basename){
      var p = Builder.node("a",{href:obj.post_url},obj.post_url_basename);
      if(obj.saved_url && obj.saved_name){
        var f = Builder.node("a",{href:obj.saved_url},obj.saved_name);
      } else {
        var f = Builder.node("b","error");
        d.style.backgroundColor = "#FF5555";
      }
      d.appendChild(p); d.appendChild(br); d.appendChild(f);
      $("repport--foot").appendChild(d);
      new Effect.Highlight(d,{duration: 2});
    } else alert('global error on report_status.display function');
  }
};
JSEVAL;
/*        $eval .= 'var repport_status = {' .
              'total: 0,' .
              'count: 0,' .
              'onComplete: function(){' .
              ' var p = Math.round(100*this.count/this.total);' .
              ' $("repport---percent").innerHTML = p + " %";' .
              ' if(p == 100){' .
              '   $("repport---status").innerHTML = "Download complete"; ' .
              '   new Effect.Highlight("repport---status",{duration: 8, startcolor:"#FFFFAA", endcolor:"#2685AF", restorecolor:"#2685AF"});' .
              '   repport_status = null;' .
              '   xorax_wp_ajax_reload_field("repport");' .
              ' } else new Effect.Highlight("repport---status",{duration: 1, startcolor:"#0000AA"});' .
              '},' .
              'display (obj){' .
              ' var d = Builder.node("div", {style:"float:left; border: 1px solid #000099; padding: 3px; margin: 5px;"});' .
              ' var br = Builder.node("br");' .
              ' if(obj.post_url && obj.post_url_basename){' .
              '   var p = Builder.node("a",{href:obj.post_url},obj.post_url_basename);' .
              '   if(obj.saved_url && obj.saved_name){' .
              '     var f = Builder.node("a",{href:obj.saved_url},obj.saved_name);' .
              '   } else {' .
              '     var f = Builder.node("b","error");' .
              '   }' .
              '   d.appendChild(p); d.appendChild(br); d.appendChild(f);' .
              '   $("repport--foot").appendChild(d);' .
              '   new Effect.Highlight(d,{duration: 2});' .
              ' }' .
              '}; ';
*/
        if($method2get == 'ajaxallin1'){
          $n = count($this->posts_audio);
          $eval .= "repport_status.total = $n;\n";
          for($i=0; $i < $n; $i++){
            $eval .= 'xorax_wp_ajax_callback("save_callback",posts_audio['.$i.']);'."\n";
          }
        } else {
          $eval .= "repport_status.total = posts_audio.length;\n";
          $eval .= 'xorax_wp_ajax_callback("save_callback",posts_audio.shift());';
        }
        return array(
          'eval' => $eval,
          'foot' => '<p id="repport---status">please wait during transfert : <b id="repport---percent">0 %</b></p>'
        );
      }
    } else echo 'error: '.implode(' -- ',$this->err);
  }
  
  
  function field_repport () {
    global $wpdb;
    $method2get = $this->option('method2get');
    $files = array();
    if($method2get != 'url')
      $files = $this->list_audio_files();
    
    $audios = array(
      'obsolete_id' => array(),
      'missed_id' => array(),
      'ok_id' => array()
    );
    //print_r($audios['files']);
    
    $posts = $wpdb->get_results("SELECT `ID` ,`post_modified`, `post_date`, `post_name` FROM `" . $wpdb->posts . "` WHERE (post_status = 'publish' OR post_status = 'private')");
    
    foreach($posts as $post){
      $url = get_the_audio_url(true, $post);
      if(!$url) $audios['missed_id'][] = $post->ID;
      else {
        if($url['outdate']) $audios['obsolete_id'][] = $post->ID;
        else $audios['ok_id'][] = $post->ID;
        $files[$post->ID] = ($method2get == 'url') ? $url['url'] : file_post2audio($post->post_name);
      }
      /*
      $as_file = false;
      $time = 0;
      
      if($method2get == 'url'){
        $u = readthis_meta($post->ID);
        if(!empty($u) && count($u) == 2){
          $time = $u['upd']; //$audios['fmtime'][$post->ID]
          $files[$post->ID] = $u['url'];
          $as_file = true;
        }
      }else{
        $file = file_post2audio($post->post_name);
        if(false !== $k = array_search(basename($file), $files)){
          $time = filemtime($file); //$audios['fmtime'][$k]
          $as_file = true;
        }
      }

      if( $as_file ){ //false !== $k
        if( mysql2date('U', $post->post_modified) > $time ){ //$audios['fmtime'][$k]
          $audios['obsolete_id'][] = $post->ID;
        } else {
          $audios['ok_id'][] = $post->ID;
        }
      } else {
        $audios['missed_id'][] = $post->ID;
      }
      */
    }
    $audios['files'] = &$files;
    
    if($method2get == 'url'){
      _e('The files represent URLs of ReadSpeaker audio file. The files are <b>not download</b> on this server, this is the URLs which will be gets. This is legal.<br/> However, you can not read the sounds files with SWF stored on this server because flash have a security include in : the access is prohibited for files not on same domain of the SWF except if the taget domain have a regulation file.<br /> For hack that, the default template use the readspeaker flash player. <b>You can\'t include your player</b>.','readthis');
    } else {
      _e('The files are on this server. This action will <b>download</b> selected files on this server. <b>This is not legaly</b>, ReadSpeaker don\'t accept it, but, you can do it.','readthis');
      echo "<br />\n";
      if( $method2get == 'server'){
        _e('This will took a long time because you have selected the Server method and so the download will not asynchronous. Select one of ajax methods for happy download !','readthis');
      } else {
        _e('The method to download is an asynchronous ajax method. That\'s fun :)','readthis');
      }
    }
    
    if(!$this->option('url')) {
      echo '<br />'.__('the URL of the ReadSpeaker\'s XML is empty. You <b>MUST</b> set it to perform this action. check also the method of downloading.','readthis');
    }
    
    $c_obs = count($audios['obsolete_id']);
    $c_ok = count($audios['ok_id']);
    $c_miss = count($audios['missed_id']);
    ?>
    <ul>
      <li><?php echo count($files).' '.__("files audio found",'readthis'); ?></li>
      <li><?php echo $c_obs.' '.__("obsolete files",'readthis'); ?></li>
      <li><?php echo $c_ok.' '.__("files audio correct conrresponding at posts",'readthis'); ?></li>
      <li><?php echo $c_miss.' '.__("files audio missed",'readthis') ?></li>
    </ul>
    <input type="radio" name="readthis_dl_mode" value="delete" /><?php
	if($method2get == 'url') _e('Delete all URLs of audio files ','readthis');
	else _e('delete all audio files','readthis'); 
	?><br /><br />
    <?php
	if($method2get == 'url') _e('Find URL of the files','readthis');
	else _e('Download the files','readthis');
	?> :<br />
    <?php $c = $c_obs+$c_miss; ?> 
    <input type="radio" name="readthis_dl_mode" value="obsolete_missed"<?php if($c == 0) echo ' disabled'; ?> /><?php
      echo __('obsoletes and missed','readthis').' ('.$c.')'; ?><br />
    
    <?php $c = $c_obs; ?> 
    <input type="radio" name="readthis_dl_mode" value="obsolete"<?php if($c == 0) echo ' disabled'; ?> /><?php
      echo __('obsolete','readthis').' ('.$c.')'; ?><br />
      
    <?php $c = $c_miss; ?> 
    <input type="radio" name="readthis_dl_mode" value="missed"<?php if($c == 0) echo ' disabled'; ?> /><?php
      echo __('missed','readthis').' ('.$c.')'; ?><br />
      
    <?php $c = $c_obs+$c_miss+$c_ok; ?> 
    <input type="radio" name="readthis_dl_mode" value="all"<?php if($c == 0) echo ' disabled'; ?> /><?php
      echo __('which are available and overwrite all existing files/URLs','readthis').' ('.$c.')'; ?><br />
      
    <input type="hidden" name="readthis_file_repport_array" value='<?php echo base64_encode(serialize($audios)); ?>' />
    <input type="submit" name="readthis_exec_repport" value="<?php _e('execute','readthis'); ?>" /><br />
    <?php
    
    return array('title' => __('repport','readthis'));
  }
  
  function field_pass2get_action (){
    $p = $_POST['newpass'];
    $newpass = preg_replace('#[^a-z0-9\-_]#i','',$newpass);
    if($p == $newpass){
      $this->option('pass2get',$p);
      $this->option('url','');
      _e('Password reseted. You must enter the new ReadSpeaker xml url','readthis');
      return array('reload' => true, 'eval' => 'xorax_wp_ajax_reload_field("set_url");'); 
    } else {
      _e('some characters is not accepted. they must be a-z, 0-9, - or _ only.');
    }
  }
  
  function field_pass2get (){
    $urlpass = get_option('siteurl').'/feed/?rd_pass=';
    echo '<p>';
    _e("This url must be added in your ReadSpeaker's feed list : ",'readthis') ?><br />
    <input type="text" size="70" value="<?php echo $urlpass.$this->option('pass2get'); ?>" /></p>
    <p><?php echo $urlpass; ?><input type="text" size="10" name="newpass" value="" />
    <input type="submit" name="readthis_resetpass" value="<?php _e('change password','readthis'); ?>" /></p>
    <?php _e('that makes it possible to print in the ReadSpeaker\'s XML the posts selected for download them','readthis');
    return array('title' => __('special feed url','readthis'));
  }
  
  function field_set_url_action (){
    $this->option('url',$_POST['readthis_url']);
    _e('Changing url success','readthis');
    return array('reload' => true);
  }
  
  function field_set_url (){
    _e('Enter here your associed ReadSpeaker url','readthis'); ?> :<br />
    <input type="text" id="readthis_url" name="readthis_url" size="70" value="<?php echo $this->option('url'); ?>" /><br />
    <input type="submit" name="readthis_set_url" value="<?php _e('send','readthis'); ?>" />
    <?php echo __('actualy','readthis').' : '.$this->option('url');
    
    return array('title' => __('readspeaker feed xml url','readthis'));
  }
  
  function field_template_method_action(){
    if(in_array($_POST['tplmethod'], array('none','inline','widget','inline+widget'))){
      $this->option('tpl-method',$_POST['tplmethod']);
      echo __('Template method setup complete','readthis');
    } else {
      echo __('error : template method unavailiable','readthis');
    }
  }
    
  function field_template_method(){
    $tplmethod = $this->option('tpl-method');
    echo '<p>';
    _e('select the method to display the selected template.');
    _e('If this method is not availlable in the template, that display nothing.'); ?>
    <br />
    <input type="radio" name="tplmethod" value="none" <?php if($tplmethod=='none') echo 'checked '; ?>/>
    <?php _e('none : nothing will be display automaticaly. You should include functions in your WP template.');?>
    <br />
    <input type="radio" name="tplmethod" value="inline" <?php if($tplmethod=='inline') echo 'checked '; ?>/>
    <?php _e('inline : display automaticaly the template for every post.'); ?>
    <br />
    <input type="radio" name="tplmethod" value="widget" <?php if($tplmethod=='widget') echo 'checked '; ?>/>
    <?php _e('widget : display automaticaly the template in a widget'); ?>
    <br />
    <input type="radio" name="tplmethod" value="inline+widget" <?php if($tplmethod=='inline+widget') echo 'checked '; ?>/>
    <?php _e('widget + inline'); ?>
    <br />
    <input type="submit" value="<?php _e('send','readthis'); ?>" />
    </p>
    <?php
    return array('title' => __('template method'));
  }
  
  function field_template_select_action(){
    $template = $this->get_template($_POST['tplselect']);
    if($template){
      $this->option('tpl-select',$template['name']);
    }
  }
    
  function field_template_select(){
    $tplselect = $this->option('tpl-select');
    _e('select the template you will used');
    ?> : <select name="tplselect" onchange="javascript:view_template_name(this.value);"><?php
    $templates = $this->list_template();
    foreach($templates as $k => $v){
      $s = ($v['name'] == $tplselect) ? ' selected' : '';
      echo '<option value="'.$v['name'].'"'.$s.'>'.$v['info']['ReadThis Template Name'].'</option>';
    }
    ?></select>
    <script language="JavaScript" type="text/javascript">
      var view_template_name = function(name){
        $('tpl_info_'+view_template_name.actu).style.display = 'none';
        view_template_name.actu = name;
        $('tpl_info_'+view_template_name.actu).style.display = 'block';
      }
      view_template_name.actu = '<?php echo $tplselect; ?>';
    </script>
  
    <br /><?php
    foreach($templates as $k => $v){
      $s = ($v['name'] == $tplselect) ? '' : ' style="display:none"';
      echo '<div id="tpl_info_'.$v['name'].'"'.$s.'>';
      echo '<a href="'.$v['info']['ReadThis Template URI'].'"><b>'.$v['info']['ReadThis Template Name'].'</b></a> (<i>'.$v['info']['Version'].'</i>)<br />';
      //echo __('version').' : '.$v['info']['Version'].'<br />';
      echo $v['info']['Description'].'<br />';
      echo __('Author').' : <a href="'.$v['info']['Author URI'].'">'.$v['info']['Author'].'</a><br />';
      echo '</div>';
    }
    echo '<br /><input type="submit" value="'.__('send','readthis').'"> '.__('actualy','readthis').' : <i>'.$tplselect.'</i>';
    return array('title' => __('selected template','readthis'));
  }
  
  /*
  function field_set_template_action(){
    switch($_POST['readthis_template']){
    case 'url':
    case 'inline':
    case 'default':
      $this->option('templateaudio',$_POST['readthis_template']);
    break;
    case 'perso':
      $this->option('templateaudio',$_POST['template_perso']);
      //update_option('readthis_user_template',$_POST['template_perso']);
    break;
    }
    echo __('Template setup complete','readthis');
  }
  
  function field_set_template(){
    $templateaudio = $this->option('templateaudio');
    _e('This is the template which screen when the_audio() function is called','readthis'); ?><br />
    <input type="submit" name="readthis_set_url" value="<?php _e('send','readthis'); ?>" /><br />
    <input type="radio" name="readthis_template" value="inline"<?php if($templateaudio == 'inline') echo ' checked'; ?> /> <?php
    _e('inline method : use a filter at the title of the post to add the default template at the end. <b>No template modification required</b>.','readthis'); ?><br />
    <input type="radio" name="readthis_template" value="default"<?php if($templateaudio == 'default') echo ' checked'; ?> /> <?php
    _e("The default template, the_audio() print : ReadSpeaker flash player if the method to get sound is url only, or XWPlayer if you're allowed downloading method",'readthis'); ?><br />
    <input type="radio" name="readthis_template" value="url"<?php if(v == 'url') echo ' checked'; ?> /> <?php
    _e("the_audio() return only url and personnalize how use it in your template",'readthis'); ?><br />
    <input type="radio" name="readthis_template" value="perso"<?php if(!in_array($templateaudio,array('default','url','inline'))) echo ' checked'; ?> /> <?php
    _e("personnalize your template with the {READTHIS_AUDIO} var",'readthis'); ?><br />
    <textarea name="template_perso" rows="10" cols="50" wrap="off"><?php
    echo $templateaudio;
    ?></textarea><br />
    <input type="submit" name="readthis_set_url" value="<?php _e('send','readthis'); ?>" /><?php
    return array('title' => 'Template to screen');
  }
  /**/
  
  /*** OPTIONALS FONCTIONNALITIES BEGIN***/
  function field_method2get_action(){
    if($this->option('method2get') != $_POST['readthis_method'] && in_array($_POST['readthis_method'], array('ajax1by1','ajaxallin1','server','url'), true) ){
      $this->option('method2get',$_POST['readthis_method']);
      _e('method setup complete.','readthis');
      return array('reload' => true, 'eval' => 'xorax_wp_ajax_reload_field("repport");');
    } else _e('allready set at this value.','readthis'); 
  }
  
  function field_method2get(){
    _e('this set the method for download sound file on server','readthis');
    $method2get = $this->option('method2get');
    ?><br />
        <input type="radio" name="readthis_method" value="ajax1by1"<?php if($method2get == 'ajax1by1') echo ' checked'; ?> /> <?php _e('ajax one by one','readthis'); ?><br/>
        <input type="radio" name="readthis_method" value="ajaxallin1"<?php if($method2get == 'ajaxallin1') echo ' checked'; ?> /> <?php _e('ajax all in one','readthis'); ?><br/>
        <input type="radio" name="readthis_method" value="server"<?php if($method2get == 'server') echo ' checked'; ?> /> <?php _e('server','readthis'); ?><br/>
        <input type="radio" name="readthis_method" value="url"<?php if($method2get == 'url') echo ' checked'; ?> /> <?php _e('url only','readthis'); ?><br/>
        <input type="submit" name="readthis_exec_method2get" value="<?php _e('send','readthis'); ?>" /> <?php echo __('actualy','readthis').' : '.$method2get; ?>
    <?php
    return array('title' => __('method','readthis'), 'id' => 'method2get');
  }
  
  function field_path_action(){
    $newpath = untrailingslashit(trim($_POST['readthis_path']));
    
    if($newpath.'/' == $this->option('audiopath')) return true;
    
    if(!is_dir(ABSPATH.$newpath) && !mkdir(ABSPATH.$newpath)){
      return '"'.$newpath.'" '.__("don't exist and can't be created",'readthis');
    }
    
    $absaudiopath = ABSPATH.$this->option('audiopath');
    $newpath .= '/';
    $r = array();
    $audio_files = list_audio_files();

    for($i = 0, $n = count($audio_files); $i < $n; $i++){
      if(empty($_POST['readthis_path_move_audios'])){
        @unlink($absaudiopath.$audio_files[$i]);
      } else {
        rename($absaudiopath.$audio_files[$i], ABSPATH.$newpath.$audio_files[$i]);
      }
    }
    $r[] = (empty($_POST['readthis_path_move_audios']))
      ? __('All audio files were deleted','readthis')
      : __('All audio files were moved','readthis');
  
    if(!empty($_POST['readthis_path_delete'])){
      @rmdir(untrailingslashit($absaudiopath));
    }
  
    $this->option('audiopath',$newpath);
    return array('reload' => true);
  }
  
  function field_path(){
    ?>
        <?php echo __('Relative path at your blog where sound files are saved. Only Used if the method to get is not url. Default is ','readthis').' <i>wp-content/audio/</i>'; ?><br />
        <input type="text" id="readthis_path" name="readthis_path" value="<?php echo $this->option('audiopath'); ?>" width="100%"/><br />
        <input type="checkbox" id="readthis_path_delete" name="readthis_path_delete" value="1" checked />
        <?php _e('delete old directory','readthis'); ?></br>
        <input type="checkbox" id="readthis_path_move_audios" name="readthis_path_move_audios" value="1" checked />
        <?php _e('move all file of old directory in new path','readthis'); ?><br />
        <input type="submit" name="readthis_set_path" value="<?php _e('send','readthis'); ?>" /> <?php echo __('actualy','readthis').' : '.$this->option('audiopath'); ?>
    <?php
    return array('title' => __('sound files path','readthis'));
  }
  /*** OPTIONAL FONCTIONNALITY END***/
  
  /*** FOR DEBUGGING BEGIN ***/
  function field_set_getposts_action(){
    $p = explode(',',$_POST['readthis_getpoststemp']);
    $np = array();
    if(!empty($p)){
      for($i=0, $n = count($p); $i < $n; $i++){
        $id = intval(trim($p[$i]));
        if($id) $np[] = $id;
      }
    }
    $this->posts2get = $np;
    update_option("readthis_posts2get",$this->posts2get);
    
    if(empty($np)) _e('no id, reset successfull');
    else _e('set successfull');
    return array('reload' => true);
  }
  function field_set_getposts(){
    $p = is_array($this->posts2get) ? implode(',',$this->posts2get) : $this->posts2get;
    _e('set the temporary posts IDs at screen on field'); ?>
    <input type="text" name="readthis_getpoststemp" value="<?php echo $p; ?>" /><br />
    <input type="submit" name="readthis_set_getpoststemp" value="<?php _e('send','readthis'); ?>" />
    <?php echo __('actualy','readthis').' : '.$p;
    
    return array('title' => __('set temporary feed post IDs','readthis'));
  }
  /*** FOR DEBUGGING END ***/
}
}
?>